﻿using System;
using System.Text;
using Google.Protobuf;

namespace GSE.Rpc
{
    public class Response : RpcObject
    {
        protected ResponseStatus statusCode;
        public Response(ResponseStatus statusCode, UInt16 transactionID, IMessage result)
        {
            this.transactionID = transactionID;
            param = result;
            this.statusCode = statusCode;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="statusCode"></param>
        /// <param name="transactionID"></param>
        /// <param name="result">protobuf Message 序列化数据</param>
        public Response(ResponseStatus statusCode, UInt16 transactionID, byte[] result)
        {
            this.transactionID = transactionID;
            dataBytes = result;
            this.statusCode = statusCode;
        }

        public ResponseStatus GetStatus()
        {
            return statusCode;
        }

        public override string ToString()
        {
            var sb = new StringBuilder();
            sb.AppendJoin(',', param != null ? param.ToByteArray() : dataBytes);
            return $"{{TransactionID:{transactionID}, Status: {statusCode}, MessageData:[{sb.ToString()}]}}";
        }

        public override byte[] Encode()
        {
            var mb = param != null ? param.ToByteArray() : dataBytes;

            // (verNo + logicPacketType) + packet length + transaction id + status + message data
            var data = new byte[1 + 4 + 2 + 1 + mb.Length];
            var offset = 0;
            data[offset] = (protoVerNo << 3) + (byte)LogicPacketType.RPC;
            offset += 1;
            // -5, 去除固定头部的verNo和包长度.
            var dataLengthB = BitConverter.GetBytes((UInt32)(data.Length - 5));
            Array.Reverse(dataLengthB);
            Array.Copy(dataLengthB, 0, data, offset, 4);
            offset += 4;
            // transaction id

            var transactionIdB = BitConverter.GetBytes(transactionID);
            Array.Reverse(transactionIdB);
            Array.Copy(transactionIdB, 0, data, offset, 2);
            offset += 2;
            // service name 长度段.
            data[offset] = (byte)statusCode;
            offset += 1;

            // 参数内容段.
            Array.Copy(mb, 0, data, offset, mb.Length);
            return data;
        }
    }

}
